package ar.com.ironsoft.dynamicconfigloader.services

import javax.annotation.PostConstruct

import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH
import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
import org.codehaus.groovy.grails.commons.GrailsDomainClass
import org.codehaus.groovy.grails.commons.GrailsDomainClassProperty

class DynamicLoaderService {
	static transactional = true
	private Map<GrailsDomainClass,Object> configInstances = new HashMap<GrailsDomainClass,Object>();
	private boolean hasInited = false;

	@PostConstruct
	def initConfigInstances(){
		if (!hasInited){

			for (GrailsDomainClass clazz : AH.application.domainClasses){
				if (clazz.getName().endsWith("Config")){
					def instance = readFromDatabase(clazz);
					if (instance == null){
						//If config not exist I read it from Config.groovy
						instance = readFromConfig(clazz);
						
						//And persist it into database
						instance.save();
					}
					configInstances.put clazz.getClazz(), instance;
				}
			}

			hasInited = true;
		}
	}
	public static def readFromDatabase(GrailsDomainClass domainClazz){
		Class clazz = domainClazz.getClazz();
		def instance = clazz.findAll();
		return instance.size() == 0 ? null : instance.get(0);
	}

	public static def readFromConfig(GrailsDomainClass domainClazz){
		Class clazz = domainClazz.getClazz();
		def instance = clazz.newInstance();
		for (GrailsDomainClassProperty prop : domainClazz.persistantProperties){
			String propname = prop.getName();
			String configname = domainClazz.getName().toLowerCase();
			instance.@"$propname" =  CH.config.grails.getProperty(configname).getProperty(propname)
		}
		return instance;
	}

	def getConfigInstance(Class clazz){
		configInstances.get clazz;
	}
	
	def flush(Class clazz){
		def instance = readFromDatabase(new DefaultGrailsDomainClass(clazz));
		configInstances.put clazz, instance;
		return instance
	}
}
